package com.tedu.API.io;

import org.junit.Test;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * RandomAccess解决: File无法实现读写操作
 *
 * RandomAccess类:   随机访问文件类
 * 功能: 实现“文件"和文件夹实现数据读写操作,底层使用C语言，以二进制数据为核心
 *                                    底层:二进制数据
 * 创建随机访问文件类
 * RandomAccessFile  raf=new RandomAccessFile("路径+文件全称","rw");
 * RandomAccessFile  raf=new RandomAccessFile("路径+文件全称","r");
 * 第二个参数[mode  模式]: r  模式---->该文件可以读操作
 *                      rw  模式---->该文件可以读写操作
 * 需求: 实现CV   复制音乐/视频
 */
public class RandomAccessFileAPI {
    @Test
    public void testRAF() throws IOException {
        //RandomAccessFile 对象创建出来---路径+全称  |   模式: "rw"
        RandomAccessFile raf=
                new RandomAccessFile("raf.txt","rw");
        //1.在API项目文件夹下创建raf.txt文件，并且实现读写操作

        //计算机  识别： 二进制    0000 0000
        /**
         * 需要往raf.txt 写出一个  a 字母
         * write(整数: 十进制)    十进制  转换为计算机识别二进制
         *      整数范围: 0~255   十进制ASCII码  二进制---十进制--字母
         *                                              97     a
         *                                              98     b
         * 作用: 往文件中写出一个字节,抛出一个IO流异常: 存在写出失败情况
         *      将整数低八位写出到文件当中
         *      1字节==8位二进制     0000 0001    1
         *                         0000 0010    2
         *                         0000 0011    3
         *                         0000 0110    6
         *
         *      1024字节==1KB
         *      1024KB ==1MB
         *      1024MB ==1G
         *      1024G  ==1T
         */
        raf.write(97);  //写出: 一个字节，识别二进制，写十进制转二进制
        raf.write(98);
        raf.write(101);
        //write方法---一个字节一个字节写出
        //关闭流   close()
        raf.close();
    }

    /**
     * read()方法:
     * 作用: 读取一个字节，十进制的 int类型返回，如果文件读到-1，代表结束
     *      存在IO流异常: 读取可能失败
     */
    @Test
    public void testRead() throws IOException {
        //创建对象: 随机访问文件的对象---只读操作---raf.txt文件的内容
        RandomAccessFile raf=
                new RandomAccessFile("raf.txt","r");
        int i=raf.read();   //read() 方法存在异常
        System.out.println(i);  //"a"----ASCII码---97
        int j=raf.read();       //"b"---ASCII码--98
        System.out.println(j);
        int k= raf.read();     //"e"---ASCII码--101
        System.out.println(k);
        int y= raf.read();    //-1  代表  文件没有数据
        System.out.println(i+" "+j+" "+k+" "+y);
    }

    /**
     * RAF类---构造器实现: 读写操作--
     *          -write(数值)  read()  一个字节一个字节写出以及读入
     *  需求: 复制粘贴一个音乐     【version 1--不考虑效率】
     */
    @Test
    public void testCV() throws IOException {
        //1.源文件--"小跳蛙.mp3" -------复制---操作: 读入
        RandomAccessFile src=
                new RandomAccessFile("小跳蛙.mp3","r");
        //2.复制文件--"新跳蛙.mp3"------粘贴---操作: 写出
        RandomAccessFile desc=
                new RandomAccessFile("新跳蛙.mp3","rw");
        //3.用于保存读写到的字节: 作用:①保存一个字节 ②-1代表文件读取到末尾
        int data=-1;
        //4.一直从小跳蛙.mp3中一个字节一个字节的读取---[true]
        //   同时一个字节一个字节的写出"新跳蛙.mp3"
        //   data=sre.read()  作为条件判断语句写入
        //   (data=src.read())!=-1    条件判断语句[true]
        long start=System.currentTimeMillis();//获取到当前系统时间毫秒数
        while ((data=src.read())!=-1){  //一个字节一个字节的读
            // 同时一个字节一个字节的写出"新跳蛙.mp3"
            desc.write(data);
        }
        long end=System.currentTimeMillis();
        System.out.println("粘贴复制花费多少: "+(end-start)/1000+"秒");
    }

    /**
     * 需求: 复制粘贴一个音乐  【Version 1--考虑效率】
     *  一个字节一个字节读物---一个字节一个字节写出    【慢】
     *  100KB读取---  100KB写出                  【快】
     */
    @Test
    public void testCVS() throws IOException {
        //1.从API目录下"小跳蛙.mp3"---读取数据【100KB】
        RandomAccessFile raf=new RandomAccessFile("小跳蛙.mp3","r");
        //2.从API目录下写出"效率高.mp3"---写出数据【100KB】
        RandomAccessFile dgk=new RandomAccessFile("效率高.mp3","rw");
        //3.保存每次读取字节量: ①覆盖: 保存读写数据,保障数据稳定
        //                   ②没有数据: 表示文件读取到末尾   值为-1
        int len=-1;
        //4.效率: 100KB      字节数组: byte
        byte[] data=new byte[1024*100];   //100KB
        //5. 一直  从raf文件当中读取数据: 100KB   |  read(byte[] b) 读100KB字节
        //5.1  raf.read()   从raf"小跳蛙.mp3"里 一个字节一个字节的读
        //5.2  raf.read(byte[] data)   从raf"小跳蛙.mp3"   100KB的读
        //5.3  len=raf.read(byte[] data)  保存从raf"小跳蛙.mp3"   100KB的读
        //5.4  (len=raf.read(byte[] data))!=-1
        //     将读到的100KB的字节数据保存len中,只要不等于-1,没有读完,一直读
        long start=System.currentTimeMillis();//获取到当前系统时间毫秒数
        while( (len=raf.read(data))!=-1  ){
            //  同时,读文件的同时，写出数据"效率高.mp3"文件
            //  write()方法  写出一个字节【慢】
            //  write(字节数组,0,-1)   写出字节数组指定的单元量【例: 100KB】
            dgk.write(data,0,len);
        }
        long end=System.currentTimeMillis();
        System.out.println("100KB复制版本: "+(end-start)+"毫秒");
        //测: 视频复制: 100KB
    }
    //测: 视频复制: 100KB
    @Test
    public void testSP() throws IOException {
      RandomAccessFile qwe=new RandomAccessFile("复制视频.mp4","r");
      RandomAccessFile asd=new RandomAccessFile("新视频.mp4","rw");
      int len=-1;
      byte[] data=new byte[1024*100];
        long start=System.currentTimeMillis();
      while ( (len= qwe.read(data))!=-1 ){
          asd.write(data,0,len);
      }
        long end=System.currentTimeMillis();
        System.out.println("新视频:  "+(end-start)+"毫秒");
    }
}
